package main;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

import components.*;

import shemes.*;

public class CPURegister extends JPanel implements ActionListener {

    private static final long serialVersionUID = 1L;
    private JButton izmeni;
    private JButton izadji;
    private JDialog greska;
    private JDialog potvrda;
    private boolean error;
    private JTextField[] regPolja;
    private REG[] allRegs;
    private JDialog sadrzalacRegistara;
    JTextField[] PSWbits = new JTextField[9];

    public JDialog getSadrzalacRegistara() {
        return sadrzalacRegistara;
    }

    public void setSadrzalacRegistara(JDialog sadrzalacRegistara) {
        this.sadrzalacRegistara = sadrzalacRegistara;
    }

    public CPURegister() {

        setLayout(new BorderLayout());
        setBackground(Color.white);
        allRegs = new REG[51];
        for (int i = 0; i < 32; i++) {
            allRegs[i] = Adr1.GPR().getREG(i);
        }
        allRegs[32] = Bus1.RegMAR();
        allRegs[33] = Bus1.RegMDR();
        allRegs[34] = Bus1.RegDWH();
        allRegs[35] = Bus1.RegDWL();
        allRegs[36] = Fetch1.RegPC();
        allRegs[37] = Fetch1.RegIR0();
        allRegs[38] = Fetch1.RegIR1();
        allRegs[39] = Fetch1.RegIR2();
        allRegs[40] = Fetch1.RegIR3();
        allRegs[41] = Adr1.RegSP();
        allRegs[42] = Adr1.RegGPRAR();
        allRegs[43] = Adr1.RegCW();
        allRegs[44] = Exec1.RegAB();
        allRegs[45] = Exec1.RegBB();
        allRegs[46] = Exec1.RegAW();
        allRegs[47] = Exec1.RegBW();
        allRegs[48] = Intr1.RegIMR();
        allRegs[49] = Intr3.RegBR();
        allRegs[50] = Intr3.RegIVTP();
    }

    public void init() {
        Color bgcolor = Color.white;
        JPanel registrisvi = new JPanel(new GridLayout(1, 4));
        registrisvi.setBackground(bgcolor);

        this.regPolja = new JTextField[59];

        JPanel prvi = new JPanel(new GridLayout(16, 2));
        prvi.setBackground(bgcolor);
        for (int i = 0; i < 16; i++) {
            JLabel ime = new JLabel("R" + i + ": ");
            ime.setVerticalAlignment(0);
            ime.setHorizontalAlignment(4);
            prvi.add(ime);
            JPanel tmp = new JPanel();
            tmp.setBackground(bgcolor);
            regPolja[i] = new JTextField(5);// 5 je broj kolona
            regPolja[i].setColumns(3);
            regPolja[i].setText(Integer.toHexString(allRegs[i].getVal()));
            tmp.add(regPolja[i]);
            prvi.add(tmp);
        }

        registrisvi.add(prvi);

        JPanel drugi = new JPanel(new GridLayout(16, 2));
        drugi.setBackground(bgcolor);
        for (int i = 16; i < 32; i++) {
            JLabel ime = new JLabel("R" + i + ": ");
            ime.setVerticalAlignment(0);
            ime.setHorizontalAlignment(4);
            drugi.add(ime);
            JPanel tmp = new JPanel();
            tmp.setBackground(Color.white);
            regPolja[i] = new JTextField(5);
            regPolja[i].setColumns(3);
            regPolja[i].setText(Integer.toHexString(allRegs[i].getVal()));
            tmp.add(regPolja[i]);
            drugi.add(tmp);
        }

        registrisvi.add(drugi);


        JPanel treci = new JPanel(new GridLayout(16, 2));
        treci.setBackground(bgcolor);

        JLabel name;
        JPanel temp;

        name = new JLabel("MAR: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[32] = new JTextField();
        regPolja[32].setColumns(3);
        regPolja[32].setText(Integer.toHexString(allRegs[32].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[32]);
        treci.add(temp);

        name = new JLabel("MDR: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[33] = new JTextField();
        regPolja[33].setColumns(3);
        regPolja[33].setText(Integer.toHexString(allRegs[33].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[33]);
        treci.add(temp);

        name = new JLabel("DWH: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[34] = new JTextField();
        regPolja[34].setColumns(3);
        regPolja[34].setText(Integer.toHexString(allRegs[34].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[34]);
        treci.add(temp);

        name = new JLabel("DWL: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[35] = new JTextField();
        regPolja[35].setColumns(3);
        regPolja[35].setText(Integer.toHexString(allRegs[35].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[35]);
        treci.add(temp);

        name = new JLabel("PC: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[36] = new JTextField();
        regPolja[36].setColumns(3);
        regPolja[36].setText(Integer.toHexString(allRegs[36].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[36]);
        treci.add(temp);

        name = new JLabel("IR0: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[37] = new JTextField();
        regPolja[37].setColumns(3);
        regPolja[37].setText(Integer.toHexString(allRegs[37].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[37]);
        treci.add(temp);

        name = new JLabel("IR1: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[38] = new JTextField();
        regPolja[38].setColumns(3);
        regPolja[38].setText(Integer.toHexString(allRegs[38].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[38]);
        treci.add(temp);

        name = new JLabel("IR2: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[39] = new JTextField();
        regPolja[39].setColumns(3);
        regPolja[39].setText(Integer.toHexString(allRegs[39].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[39]);
        treci.add(temp);

        name = new JLabel("IR3: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[40] = new JTextField();
        regPolja[40].setColumns(3);
        regPolja[40].setText(Integer.toHexString(allRegs[40].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[40]);
        treci.add(temp);

        name = new JLabel("SP: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[41] = new JTextField();
        regPolja[41].setColumns(3);
        regPolja[41].setText(Integer.toHexString(allRegs[41].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[41]);
        treci.add(temp);

        name = new JLabel("GPRAR: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[42] = new JTextField();
        regPolja[42].setColumns(3);
        regPolja[42].setText(Integer.toHexString(allRegs[42].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[42]);
        treci.add(temp);

        name = new JLabel("CW: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[43] = new JTextField();
        regPolja[43].setColumns(3);
        regPolja[43].setText(Integer.toHexString(allRegs[43].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[43]);
        treci.add(temp);

        name = new JLabel("AB: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[44] = new JTextField();
        regPolja[44].setColumns(3);
        regPolja[44].setText(Integer.toHexString(allRegs[44].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[44]);
        treci.add(temp);

        name = new JLabel("BB: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[45] = new JTextField();
        regPolja[45].setColumns(3);
        regPolja[45].setText(Integer.toHexString(allRegs[45].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[45]);
        treci.add(temp);

        name = new JLabel("AW: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[46] = new JTextField();
        regPolja[46].setColumns(3);
        regPolja[46].setText(Integer.toHexString(allRegs[46].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[46]);
        treci.add(temp);

        name = new JLabel("BW: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        treci.add(name);
        regPolja[47] = new JTextField();
        regPolja[47].setColumns(3);
        regPolja[47].setText(Integer.toHexString(allRegs[47].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[47]);
        treci.add(temp);


        registrisvi.add(treci);

        JPanel cetvrti = new JPanel(new GridLayout(16, 2));
        cetvrti.setBackground(bgcolor);

        name = new JLabel("IMR: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        cetvrti.add(name);
        regPolja[48] = new JTextField();
        regPolja[48].setColumns(3);
        regPolja[48].setText(Integer.toHexString(allRegs[48].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[48]);
        cetvrti.add(temp);

        name = new JLabel("BR: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        cetvrti.add(name);
        regPolja[49] = new JTextField();
        regPolja[49].setColumns(3);
        regPolja[49].setText(Integer.toHexString(allRegs[49].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[49]);
        cetvrti.add(temp);

        name = new JLabel("IVTP: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        cetvrti.add(name);
        regPolja[50] = new JTextField();
        regPolja[50].setColumns(3);
        regPolja[50].setText(Integer.toHexString(allRegs[50].getVal()));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(regPolja[50]);
        cetvrti.add(temp);

        //////////////////////


        name = new JLabel("PSWN: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        cetvrti.add(name);
        PSWbits[0] = new JTextField();
        PSWbits[0].setEnabled(false);
        PSWbits[0].setColumns(3);
        PSWbits[0].setText(Integer.toString((Exec2.PSWN().getBoolVal() ? 1 : 0)));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(PSWbits[0]);
        cetvrti.add(temp);

        name = new JLabel("PSWZ: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        cetvrti.add(name);
        PSWbits[1] = new JTextField();
        PSWbits[1].setEnabled(false);
        PSWbits[1].setColumns(3);
        PSWbits[1].setText(Integer.toString((Exec2.PSWZ().getBoolVal() ? 1 : 0)));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(PSWbits[1]);
        cetvrti.add(temp);

        name = new JLabel("PSWC: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        cetvrti.add(name);
        PSWbits[2] = new JTextField();
        PSWbits[2].setEnabled(false);
        PSWbits[2].setColumns(3);
        PSWbits[2].setText(Integer.toString((Exec2.PSWC().getBoolVal() ? 1 : 0)));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(PSWbits[2]);
        cetvrti.add(temp);

        name = new JLabel("PSWV: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        cetvrti.add(name);
        PSWbits[3] = new JTextField();
        PSWbits[3].setEnabled(false);
        PSWbits[3].setColumns(3);
        PSWbits[3].setText(Integer.toString((Exec2.PSWV().getBoolVal() ? 1 : 0)));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(PSWbits[3]);
        cetvrti.add(temp);

        name = new JLabel("PSWI: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        cetvrti.add(name);
        PSWbits[4] = new JTextField();
        PSWbits[4].setEnabled(false);
        PSWbits[4].setColumns(3);
        PSWbits[4].setText(Integer.toString((Exec2.PSWI().getBoolVal() ? 1 : 0)));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(PSWbits[4]);
        cetvrti.add(temp);

        name = new JLabel("PSWT: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        cetvrti.add(name);
        PSWbits[5] = new JTextField();
        PSWbits[5].setEnabled(false);
        PSWbits[5].setColumns(3);
        PSWbits[5].setText(Integer.toString((Exec2.PSWT().getBoolVal() ? 1 : 0)));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(PSWbits[5]);
        cetvrti.add(temp);

        name = new JLabel("PSWL0: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        cetvrti.add(name);
        PSWbits[6] = new JTextField();
        PSWbits[6].setEnabled(false);
        PSWbits[6].setColumns(3);
        PSWbits[6].setText(Integer.toString((Exec2.PSWL0().getBoolVal() ? 1 : 0)));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(PSWbits[6]);
        cetvrti.add(temp);

        name = new JLabel("PSWL1: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        cetvrti.add(name);
        PSWbits[7] = new JTextField();
        PSWbits[7].setEnabled(false);
        PSWbits[7].setColumns(3);
        PSWbits[7].setText(Integer.toString((Exec2.PSWL1().getBoolVal() ? 1 : 0)));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(PSWbits[7]);
        cetvrti.add(temp);

        name = new JLabel("PSWL2: ");
        name.setVerticalAlignment(0);
        name.setHorizontalAlignment(4);
        cetvrti.add(name);
        PSWbits[8] = new JTextField();
        PSWbits[8].setEnabled(false);
        PSWbits[8].setColumns(3);
        PSWbits[8].setText(Integer.toString((Exec2.PSWL1().getBoolVal() ? 1 : 0)));
        temp = new JPanel();
        temp.setBackground(Color.white);
        temp.add(PSWbits[8]);
        cetvrti.add(temp);

        for (int i = 0; i < 8; i++) {
            JLabel tmp1 = new JLabel("  ");
            cetvrti.add(tmp1);
        }
        ////////////////////////
        cetvrti.setBackground(Color.white);

        registrisvi.add(cetvrti);

        add(registrisvi, "Center");

        JPanel komande = new JPanel();
        komande.setBackground(bgcolor);

        izmeni = new JButton("Change");
        izmeni.addActionListener(this);

        izadji = new JButton("Cancel ");
        izadji.addActionListener(this);

        komande.add(this.izmeni);
        komande.add(this.izadji);
        add(komande, "South");
    }

    public void actionPerformed(ActionEvent arg0) {

        int[] nizvrednosti = new int[50];
        if (arg0.getActionCommand().equals("Change")) {
            for (int i = 0; i < 50; i++) {
                int val = proverivred(regPolja[i].getText(), i);
                if (error) {
                    break;
                }
                nizvrednosti[i] = val;
            }

            if (!error) {
                for (int i = 0; i < 50; i++) {
                    allRegs[i].setVal(nizvrednosti[i]);
                }
                potvrda = new JDialog();
                potvrda.setSize(350, 100);
                potvrda.setLocation(200, 200);
                potvrda.setModal(true);
                potvrda.setTitle("Potvrda");
                JPanel osnovni = new JPanel(new GridLayout(2, 1));
                JLabel lab = new JLabel(
                        "Promena sadrzaja registara je uspesno odradjena!");
                lab.setHorizontalAlignment(0);
                osnovni.add(lab);
                JButton ok = new JButton("U redu");
                ok.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent arg0) {
                        potvrda.setVisible(false);

                    }
                });
                JPanel tmp = new JPanel();
                tmp.add(ok);
                tmp.setBackground(Color.white);
                osnovni.add(tmp);
                osnovni.setBackground(Color.white);
                potvrda.add(osnovni);
                potvrda.setVisible(true);

            } else {
                error = false;
                greska = new JDialog();
                greska.setSize(550, 150);
                greska.setLocation(200, 200);
                greska.setModal(true);
                greska.setTitle("Greska!");
                JPanel osnovni = new JPanel(new GridLayout(3, 1));
                JLabel lab = new JLabel(
                        "Neka od unetih vrednosti nije dobra (ili prelazi velicinu registra ili je unet netacan hex. broj).");
                lab.setHorizontalAlignment(0);
                osnovni.add(lab);
                JLabel lab1 = new JLabel(
                        "Zato se brisu sve tekuce izmene registara!");
                lab1.setHorizontalAlignment(0);
                osnovni.add(lab1);
                JButton ok = new JButton("U redu");
                ok.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent arg0) {
                        greska.setVisible(false);
                        sadrzalacRegistara.setVisible(true);// da se ugasi i
                        // pregled
                        // registara jer
                    } // ako se on ne ugasi onda ostaju da se vide te nevalidne
                    // vrednosti koje
                }); // idu van opsega
                JPanel tmp = new JPanel();
                tmp.add(ok);
                tmp.setBackground(Color.white);
                osnovni.add(tmp);
                osnovni.setBackground(Color.white);
                greska.add(osnovni);
                greska.setVisible(true);
            }
        } else {// ako je izadji
            sadrzalacRegistara.setVisible(false);
        }
        repaint();
    }

    private int proverivred(String text, int i) {
        int val;
        try {
            val = Integer.parseInt(text, 16);
        } catch (Exception e) { // ZBOG NUMBER FORMAT EXCEPTION!
            error = true;
            return 0;
        }

        int validBits;
        if (allRegs[i].getOut(0).isBool()) {
            validBits = allRegs[i].getOut().length;
        } else {
            validBits = allRegs[i].getOut(0).getNumOfLines();
        }
        if ((int) Math.pow(2.0D, validBits) <= val) {
            error = true;
        }

        return val;
    }

    public void paint(Graphics g) {
        super.paint(g);
        for (int i = 0; i <= 50; i++) {
            if (i == 33 || i == 34 || i == 35 || i == 37 || i == 38 || i == 39 || i == 40 || i == 42 || i == 44 || i == 45 || i == 49) {
                regPolja[i].setText(String.format("%02x", allRegs[i].getVal()));

            } else {
                regPolja[i].setText(String.format("%04x", allRegs[i].getVal()));

            }
        }

        PSWbits[0].setText(Integer.toString(Exec2.PSWN().getBoolVal() ? 1 : 0));
        PSWbits[1].setText(Integer.toString(Exec2.PSWZ().getBoolVal() ? 1 : 0));
        PSWbits[2].setText(Integer.toString(Exec2.PSWC().getBoolVal() ? 1 : 0));
        PSWbits[3].setText(Integer.toString(Exec2.PSWV().getBoolVal() ? 1 : 0));
        PSWbits[4].setText(Integer.toString(Exec2.PSWI().getBoolVal() ? 1 : 0));
        PSWbits[5].setText(Integer.toString(Exec2.PSWT().getBoolVal() ? 1 : 0));
        PSWbits[6].setText(Integer.toString(Exec2.PSWL0().getBoolVal() ? 1 : 0));
        PSWbits[7].setText(Integer.toString(Exec2.PSWL1().getBoolVal() ? 1 : 0));
        PSWbits[8].setText(Integer.toString(Exec2.PSWL2().getBoolVal() ? 1 : 0));

    }
}
